package com.zrrd.straw1.vo;

import com.zrrd.straw1.service.impl.ServiceException;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 统一响应对象
 * 泛型参数： 内部定义方法时，可以使用泛型来表示将来使用的类型对象。T.toString();
 *
 * Serializable 接口：标记接口，没有方法，给虚拟机（JVM) 看的。表示可以被序列你给的。
 * 主要应用场景： 保存到磁盘，网络传输
 * Java 对象 转换成字节过程 叫序列化
 * 字节 斩换成 Java对象过程 叫反序列化。
 * @param <T> 类型参数
 */
@Data
@Accessors(chain = true) //lombok注解、支持链式调用
public class Result<T> implements Serializable {
    // idea 快捷键  Ctrl + D  快速复制一行代码
    //服务器成功返回数据
    public static final int OK = 200;
    //用户创建或修改数据成功
    public static final int CREATED = 201 ;
    //异步任务：当前请求已进入后台排队
    public static final int ACCEPTED = 202 ;
    //用户删除数据成功
    public static final int NO_CONTENT = 204 ;
    //用户发送错误的数据请求，服务器没有新建或修改数据
    public static final int INVALID_REQUEST = 400 ;
    //用户没有权限（令牌，用户名，密码错误）认证失败
    public static final int UNAUTHORIZED = 401 ;
    //用访得到访问授权，但是访问是被禁止的。（与401相对，认证成功，但没有访问权限）
    public static final int FORBIDEN = 403 ;
    //用户访问不存在的资源，服务器没有操作。
    public static final int NOT_FOUND = 404 ;
    //用户请求的资源被永久删除，且不会再得到
    public static final int GONE = 410 ;
    //当创建一个对象时，发生一个验证错误
    public static final int UNPROCESSABLE_ENTITY = 422 ;
    //服务器发生错误，用户将无法判断发送的请求是否成功。
    public static final int INTERNAL_SERVER_ERROR = 500 ;

    //主要是为了响应异步请求。
    //需要提供 setter/getter 方法。可以使用 lombok 注解
    private int code ;
    private String message ;
    private T data ;

    public static Result ok(String message){
        /*
        Result result = new Result();
        result.setCode(OK);   //返回的状态码定义死，防止错误的使用。
        result.setMessage(message);
        return result;
        */
        //使用lombok的 Accessor 注解
        return new Result().setCode(OK).setMessage(message);
    }
    //服务器成功返回用户请求的数据
    public static Result ok( Object data){
        return new Result().setCode(OK).setMessage("OK").setData( data );
    }
    //用户新建或修改数据成功
    public static Result created(String message){
        return new Result().setCode(CREATED).setMessage(message);
    }

    // idea 快捷键  ctrl + d  , 复制选中的代码
    // 新增之后，实时显示到页面上新增内容
    public static Result created(Object data){
        return new Result()
                .setCode(CREATED)
                .setMessage("新增完成")
                .setData( data );
    }




    //用户请求数据已经进入后台排队（异步请求）
    public static Result accepted(String message){
        return new Result().setCode(ACCEPTED).setMessage(message);
    }
    //用户删除数据成功
    public static Result noContent(String message){
        return new Result().setCode(NO_CONTENT).setMessage(message);
    }
    //400 用户发送的请求有错误，服务器没有新建或修改数据
    public static Result invalidRequest(String message){
        return new Result().setCode(INVALID_REQUEST).setMessage(message);
    }
    //401 用户没有权限（令牌，用户名，密码错误）
    public static Result unauthorized(String message){
        return new Result().setCode(UNAUTHORIZED).setMessage(message);
    }
    //403 登录成功以后，但没有足够访问权限
    public static Result forbidden(){
        return new Result().setCode(FORBIDEN).setMessage("权限不足");
    }
    //404 用户访问不存在的资源，服务器没有进行操作
    public static Result notFound(String message){
        return new Result().setCode(NOT_FOUND).setMessage(message);
    }
    //410 用户访问的资源被永久删除，且不会再得到的。
    public static Result gone(String message){
        return new Result().setCode(GONE).setMessage(message);
    }
    //422 当创建一个对象时，发生验证错误
    public static Result unprocesableEntity(String message){
        return new Result().setCode(UNPROCESSABLE_ENTITY).setMessage(message);
    }

    //500 是服务器内部错误。结合之前定义的异常类，异常类中封装了错误的详细信息。
    //将异常消息复制到返回结果中（主要针对业务层面的错误）
    public static Result failed(ServiceException e){
        return new Result().setCode( e.getCode()).setMessage(e.getMessage());
    }
    //业务之外的异常，封装到 Throwalbe 中。包括 Exception, Error
    public static Result failed( Throwable e){
        return new Result().setCode(INTERNAL_SERVER_ERROR).setMessage(e.getMessage());
    }

















}
